<?php
namespace app\index\controller;

use app\index\model\ErrorCode;
use app\utils\CryptUtils;
use app\utils\CacheUtils;
use think\Exception;
use think\Input;

class Index extends Base
{

    private $time;
    private $data;//加密过的数据
    private $type;
    private $sign;
    private $alg;
    private $api_ver;    //当前接口的版本，数字从100开始计数
    private $app_version;//当前软件的版本
    private $app_type;   //当前软件的类型 ，ios，android

    private $decrypt_data; //解密过的数据

    public function index()
    {


        $api_type = preg_replace("/_/","/",substr(ltrim($this->type),3),1);
        $api_type = preg_split("/\//",$api_type);

        if(count($api_type) < 2){
            $this->apiReturnErr("type参数不正确!",ErrorCode::Invalid_Parameter);
        }

        $action_name = $api_type[1];
        $controller_name = $api_type[0];

        $domainClass = $controller_name.'Domain/'.$action_name;
        $_POST = $this->decrypt_data;
        $_POST['domain_class'] = $domainClass;

        addLog($domainClass,$_GET,$_POST,"[接口调用开始]");
        $result = R($domainClass,array(),'domain');

        addLog($domainClass,$result,$_POST,"[接口调用结果]");

        if(!$result['status']){
            $this->apiReturnErr($result['info'],ErrorCode::Business_Error);
        }

        //1. 这一步不会走到
        $this->apiReturnErr("无法处理!",ErrorCode::Business_Error);

    }

    protected function _initialize(){

        addLog("_initialize",$_GET,$_POST,"[接口初始化]");
        $this->_initParameter();
        $this->_check();

        CacheUtils::initAppConfig();
    }



    /**
     * 初始化公共参数
     */
    private function _initParameter(){

        //1. 获取time参数
        if(isset($_POST['time'])) {
            $this->time = floatval($_POST['time']);
            unset($_POST['time']);
            if (!is_float($this->time)) {
                $this->apiReturnErr("时间戳格式非法!", ErrorCode::Invalid_Parameter);
            }
        }else{
            $this->apiReturnErr("time参数缺失!",ErrorCode::Lack_Parameter);
        }

        //2. 获取sign参数
        if(isset($_POST['sign'])){
            $this->sign = Input::post('sign','');
            unset($_POST['sign']);
        }else{
            $this->apiReturnErr("sign参数缺失!",ErrorCode::Lack_Parameter);
        }


        //3. 获取data参数
        if(!isset($_POST['data'])) {
            $this->apiReturnErr("data参数缺失!",ErrorCode::Lack_Parameter);
        }else{
            $this->data = $_POST['data'];
            unset($_POST['data']);
        }
        //4.获取type参数
        if(!isset($_POST['type'])) {
            $this->apiReturnErr("type参数缺失!",ErrorCode::Lack_Parameter);
        }else {
            $this->type = $_POST['type'];
            unset($_POST['type']);
        }
        //5.获取type参数
        if(!isset($_POST['alg'])) {
            $this->apiReturnErr("alg参数缺失!",ErrorCode::Lack_Parameter);
        }
        $this->alg = strtolower($_POST['alg']);

        if(!in_array($this->alg,array('md5'))){
            $this->apiReturnErr("alg=".$this->alg.",参数非法!",ErrorCode::Invalid_Parameter);
        }

        unset($_POST['alg']);

        //5.获取notify_id参数
        if(!isset($_POST['notify_id'])) {
            $this->apiReturnErr("notify_id参数缺失!",ErrorCode::Lack_Parameter);
        }
        $this->notify_id = $_POST['notify_id'];
        unset($_POST['notify_id']);

        //6.获取notify_id参数
        if(!isset($_POST['api_ver'])) {
            $this->apiReturnErr("api_ver参数缺失!",ErrorCode::Lack_Parameter);
        }
        $this->api_ver = $_POST['api_ver'];
        unset($_POST['api_ver']);

        $this->app_version = isset($_POST['app_version'])?$_POST['app_version']:$this->app_version;
        $this->app_type = isset($_POST['app_type'])?$_POST['app_type']:$this->app_type;



    }

    /**
     * 解密验证
     */
    private function _check(){

        //1. 请求时间戳校验
        $now = microtime(true);//time();
        //时间误差 +- 1分钟
        // if($now - 60 > $this->time || $this->time > $now + 60){
        //     $this->apiReturnErr("该请求已失效!",ErrorCode::Invalid_Parameter);
        // }

        //2. 签名校验
        $param = array(
            'client_secret'=>$this->client_secret,
            'notify_id'=>$this->notify_id,
            'time'=>$this->time,
            'data'=>$this->data,
            'type'=>$this->type,
            'alg'=>$this->alg,
        );
        try{
            if(!CryptUtils::verify_sign($this->sign,$param)){
                $this->apiReturnErr("签名验证错误!");
            }

            //3. 数据解密
            $this->decrypt_data = $param;
            $this->decrypt_data['api_ver']     = $this->api_ver;
            $this->decrypt_data['client_id']   = $this->client_id;
            $this->decrypt_data['app_version'] = $this->app_version;
            $this->decrypt_data['app_type']    = $this->app_type;

            $data = CryptUtils::decrypt($this->data);
            foreach($data as $key=>$vo){
                $this->decrypt_data['_data_'.$key] = $vo;
            }
        }catch (Exception $e){
            $this->apiReturnErr($e->getMessage());
        }

    }

}
